package com.steam.xbcc.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.steam.xbcc.doc.CourseDoc;
import com.steam.xbcc.domain.*;
import com.steam.xbcc.dto.CourseOnlineSendMessageDto;
import com.steam.xbcc.dto.CourseSaveDto;
import com.steam.xbcc.dto.LoginContextDto;
import com.steam.xbcc.dto.UserSendMessageDto;
import com.steam.xbcc.enums.GlobalExceptionCode;
import com.steam.xbcc.feign.CourseEsService;
import com.steam.xbcc.feign.MediaFileService;
import com.steam.xbcc.mapper.CourseMapper;
import com.steam.xbcc.mapper.CourseTypeMapper;
import com.steam.xbcc.result.JSONResult;
import com.steam.xbcc.utils.LoginContextUtil;
import org.springframework.util.StringUtils;
import com.steam.xbcc.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.steam.xbcc.util.AssertUtil;
import com.steam.xbcc.vo.CourseDetailVo;
import com.steam.xbcc.vo.CourseInfoVo;
import com.steam.xbcc.vo.CourseOrderVo;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.steam.xbcc.constants.MqConstants.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wt
 * @since 2022-10-07
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private ICourseDetailService courseDetailService;
    @Autowired
    private ICourseMarketService courseMarketService;
    @Autowired
    private ICourseResourceService courseResourceService;
    @Autowired
    private ICourseSummaryService courseSummaryService;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private CourseEsService courseEsService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private ICourseChapterService courseChapterService;
    @Autowired
    private MediaFileService mediaFileService;

    @Override
    public void save(CourseSaveDto courseSaveDto) {
        Course course = courseSaveDto.getCourse();
        CourseDetail courseDetail = courseSaveDto.getCourseDetail();
        CourseMarket courseMarket = courseSaveDto.getCourseMarket();
        CourseResource courseResource = courseSaveDto.getCourseResource();
        List<Long> teacharIds = courseSaveDto.getTeacharIds();

        Course courseSave = selectByName(course.getName());
        AssertUtil.isNull(courseSave, GlobalExceptionCode.COURSE_IS_NOT_NULL);
        Long courseId = saveCourse(course, teacharIds);

        courseDetail.setId(courseId);
        courseDetailService.insert(courseDetail);

        courseMarket.setId(courseId);
        courseMarketService.insert(courseMarket);

        courseResource.setCourseId(courseId);
        courseResourceService.insert(courseResource);

        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(courseId);
        courseSummaryService.insert(courseSummary);

        courseMapper.insertCourseTeacher(courseId, teacharIds);

        courseTypeMapper.updateCourseType(course.getCourseTypeId());
    }

    @Override
    public void onLineCourse(Long courseId) {
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course, GlobalExceptionCode.COURSE_IS_NULL_ERROR);
        course.setStatus(Course.ON_STATUS);
        course.setOnlineTime(new Date());

        LoginContextDto loginContext = LoginContextUtil.getLoginContext();
        course.setLoginId(loginContext.getId());
        course.setLoginUserName(loginContext.getUsername());

        updateById(course);

        CourseDoc courseDoc = new CourseDoc();
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        CourseSummary courseSummary = courseSummaryService.selectById(courseId);
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
        BeanUtils.copyProperties(course, courseDoc);
        BeanUtils.copyProperties(courseMarket, courseDoc);
        BeanUtils.copyProperties(courseSummary, courseDoc);
        courseDoc.setTypeName(courseType.getName());
        String charge = courseMarket.getCharge() == 1?"免费":"收费";
        courseDoc.setCharge(charge);

        JSONResult jsonResult = courseEsService.saveCourseEs(courseDoc);
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCode.ERROR);

        sendSmsMessage(course);

    }

    @Override
    public CourseDetailVo getDetail(Long courseId) {
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course, GlobalExceptionCode.COURSE_IS_NULL_ERROR);
        boolean boo = Course.ON_STATUS == course.getStatus();
        AssertUtil.isTrue(boo, GlobalExceptionCode.COURSE_IS_NULL_ERROR);
        CourseSummary courseSummary = courseSummaryService.selectById(courseId);
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        CourseDetail courseDetail = courseDetailService.selectById(courseId);
        List<Teacher> teachers = courseMapper.selectTeachersByCourseId(courseId);
        Wrapper<CourseChapter> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id", courseId);
        List<CourseChapter> courseChapters = courseChapterService.selectList(wrapper);
        Map<Long, CourseChapter> courseChapterMap = courseChapters.stream().collect(Collectors.toMap(CourseChapter::getId, courseChapter -> courseChapter));
        JSONResult jsonResult = mediaFileService.getMediaFileByCourseId(courseId);
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCode.ERROR);
        Object data = jsonResult.getData();
        AssertUtil.isNotNull(data, GlobalExceptionCode.ERROR);
        List<MediaFile> mediaFiles = JSON.parseArray(data.toString(), MediaFile.class);
        mediaFiles.forEach(m ->{
            m.setFileUrl("");
            CourseChapter courseChapter = courseChapterMap.get(m.getChapterId());
            if (courseChapter != null){
                courseChapter.getMediaFiles().add(m);
            }
        });
        return new CourseDetailVo(course, courseMarket, courseChapters, teachers, courseDetail, courseSummary);
    }

    @Override
    public CourseInfoVo getInfo(String courseIds) {
        Set<Long> collect = Arrays.stream(courseIds.split(","))
                .filter(id -> !StringUtils.isEmpty(id))
                .map(id -> Long.valueOf(id))
                .collect(Collectors.toSet());
        boolean boo = collect.size() == courseIds.split(",").length;
        AssertUtil.isTrue(boo, GlobalExceptionCode.ERROR);
        List<Long> courseIdsList = collect.stream().collect(Collectors.toList());
        List<Course> courses = selectBatchIds(courseIdsList);
        AssertUtil.isNotNull(courses, GlobalExceptionCode.ERROR);
        Map<Long, CourseMarket> courseMarketMap = courseMarketService.selectBatchIds(courseIdsList).stream().collect(Collectors.toMap(CourseMarket::getId, courseMarket -> courseMarket));
        CourseInfoVo courseInfoVo = new CourseInfoVo();
        List<CourseOrderVo> courseOrderVos = new ArrayList<>();
        courses.forEach(course ->{
            CourseOrderVo courseOrderVo = new CourseOrderVo();
            boolean isOK = Course.ON_STATUS == course.getStatus();
            AssertUtil.isTrue(isOK, GlobalExceptionCode.ERROR);
            CourseMarket courseMarket = courseMarketMap.get(course.getId());
            AssertUtil.isNotNull(courseMarket, GlobalExceptionCode.ERROR);
            courseOrderVo.setCourse(course);
            courseOrderVo.setCourseMarket(courseMarket);
            courseInfoVo.setTotalAmount(courseInfoVo.getTotalAmount().add(courseMarket.getPrice()));
            courseOrderVos.add(courseOrderVo);
        });
        courseInfoVo.setCourseInfos(courseOrderVos);
        return courseInfoVo;
    }

    private void sendSmsMessage(Course course) {
        CourseOnlineSendMessageDto courseOnlineSendMessageDto = new CourseOnlineSendMessageDto();
        courseOnlineSendMessageDto.setTitle("课程发布");
        courseOnlineSendMessageDto.setContent("亲爱的用户您好，最新课程 <a href='http://127.0.0.1:6002/detail.html?courseId='"+course.getId()+"''> "+course.getName()+" </a> 发布啦，点击课程了解详情");
        List<UserSendMessageDto> userSendMessageDtos = Arrays.asList(
                new UserSendMessageDto(1L, "13330964748"),
                new UserSendMessageDto(2L, "18000534099")
        );
        courseOnlineSendMessageDto.setUserSendMessageDtos(userSendMessageDtos);
        rocketMQTemplate.sendOneWay(COURSE_SMS_TOPIC + ":" +COURSE_SMS_TAG, JSON.toJSONString(courseOnlineSendMessageDto));
    }

    private Long saveCourse(Course course, List<Long> teacharIds) {
        course.setStatus(Course.OFF_STATUS);
        course.setLoginId(4L);
        course.setLoginUserName("18000534099");
        String teacherNames = teacherService.selectBatchIds(teacharIds).stream().map(teacher -> teacher.getName()).collect(Collectors.joining(","));
        course.setTeacherNames(teacherNames);
        insert(course);
        return course.getId();
    }

    private Course selectByName(String name) {
        EntityWrapper<Course> wrapper = new EntityWrapper<>();
        wrapper.eq("name", name);
        return selectOne(wrapper);
    }
}
